package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.BsZhusu;
import com.ruoyi.system.domain.BsZhusuRoom;
import com.ruoyi.system.domain.dto.BsZhusuRoomExcelDto;
import com.ruoyi.system.domain.vo.BsZhusuRoomQueryVo;
import com.ruoyi.system.mapper.BsZhusuRoomMapper;
import com.ruoyi.system.service.BsZhusuRoomService;
import com.ruoyi.system.service.BsZhusuService;
import com.ruoyi.system.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description TODO
 * @ClassName BsZhusuRoomServiceImpl
 * @Author kenn
 * @Version 1.0.0
 * @Date 2023年10月18日 10:13:00
 */
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class BsZhusuRoomServiceImpl extends ServiceImpl<BsZhusuRoomMapper, BsZhusuRoom> implements BsZhusuRoomService {

    private final BsZhusuService zhusuService;
    private final ISysDictTypeService dictTypeService;

    @Override
    public TableDataInfo<BsZhusuRoom> pageList(PageDomain pageDomain, BsZhusuRoomQueryVo queryVo) {
        LambdaQueryWrapper<BsZhusuRoom> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BsZhusuRoom::getDelFlag, Constants.LOGIC_NOT_DELETE);
        queryWrapper.eq(BsZhusuRoom::getZhusuId, queryVo.getZhusuId());
        queryWrapper.eq(ObjectUtil.isNotNull(queryVo.getIsBreakfast()), BsZhusuRoom::getIsBreakfast, queryVo.getIsBreakfast());
        queryWrapper.eq(ObjectUtil.isNotNull(queryVo.getIsWindow()), BsZhusuRoom::getIsWindow, queryVo.getIsWindow());
        queryWrapper.like(StringUtils.isNotEmpty(queryVo.getName()), BsZhusuRoom::getRoomName, queryVo.getName());
        queryWrapper.orderByDesc(BsZhusuRoom::getCreateTime);
        PageHelper.startPage(pageDomain.getPageNum(), pageDomain.getPageSize());
        List<BsZhusuRoom> roomList = list(queryWrapper);
        buildRelationInfo(roomList);
        PageInfo<BsZhusuRoom> pageInfo = new PageInfo<>(roomList);
        return new TableDataInfo<>(pageInfo.getList(), pageInfo.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveEntity(BsZhusuRoom room) {
        LambdaQueryWrapper<BsZhusuRoom> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BsZhusuRoom::getDelFlag, Constants.LOGIC_NOT_DELETE);
        queryWrapper.eq(BsZhusuRoom::getZhusuId, room.getZhusuId());
        queryWrapper.eq(BsZhusuRoom::getRoomName, room.getRoomName());
        int sameNameCount = count(queryWrapper);
        if (sameNameCount > 0) {
            throw new BaseException("房间名称已存在");
        }
        room.setDelFlag(Constants.LOGIC_NOT_DELETE);
        return save(room);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateEntity(BsZhusuRoom room) {
        LambdaQueryWrapper<BsZhusuRoom> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BsZhusuRoom::getDelFlag, Constants.LOGIC_NOT_DELETE);
        queryWrapper.ne(BsZhusuRoom::getId, room.getId());
        queryWrapper.eq(BsZhusuRoom::getRoomName, room.getRoomName());
        int sameNameCount = count(queryWrapper);
        if (sameNameCount > 0) {
            throw new BaseException("房间名称已存在");
        }
        return updateById(room);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        Assert.notNull(id, "主键id不能为空");
        LambdaQueryWrapper<BsZhusuRoom> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BsZhusuRoom::getDelFlag, Constants.LOGIC_NOT_DELETE);
        queryWrapper.eq(BsZhusuRoom::getId, id);
        BsZhusuRoom toDelete = getOne(queryWrapper);
        Assert.notNull(toDelete, "删除失败, 刷新后重试");
        toDelete.setDelFlag(Constants.LOGIC_DELETE);
        return updateById(toDelete);
    }

    @Override
    public AjaxResult<?> export(Long zhusuId) {
        Assert.notNull(zhusuId,"住宿信息主键id不能为空");
        LambdaQueryWrapper<BsZhusuRoom> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BsZhusuRoom::getDelFlag, Constants.LOGIC_NOT_DELETE);
        queryWrapper.eq(BsZhusuRoom::getZhusuId, zhusuId);
        List<BsZhusuRoom> roomList = list(queryWrapper);
        List<BsZhusuRoomExcelDto> exportList = new ArrayList<>();
        if (CollUtil.isNotEmpty(roomList)) {
            buildRelationInfo(roomList);
            exportList = roomList.stream().map(i -> BeanUtil.copyProperties(i, BsZhusuRoomExcelDto.class)).collect(Collectors.toList());
        }
        ExcelUtil<BsZhusuRoomExcelDto> util = new ExcelUtil<>(BsZhusuRoomExcelDto.class);
        return util.exportExcel(exportList, "房间信息");
    }

    /**
     * 构建关联其他表字段信息/关联字典信息
     * @param roomList:	源数据集合
     * @return: void
     * @author: kenn
     * @date: 2023/10/18 14:33
     */
    public void buildRelationInfo(List<BsZhusuRoom> roomList) {
        if (CollUtil.isNotEmpty(roomList)) {
            List<Long> zhusuIds = roomList.stream().map(BsZhusuRoom::getZhusuId).collect(Collectors.toList());
            List<BsZhusu> zhusuList = zhusuService.listByIds(zhusuIds);
            List<SysDictData> roomTypeDictList = dictTypeService.selectDictDataByType(Constants.ZHUSU_ROOM_TYPE);
            List<SysDictData> bedTypeDictList = dictTypeService.selectDictDataByType(Constants.ZHUSU_BED_TYPE);
            Map<Long, BsZhusu> zhusuMap = null;
            Map<String, SysDictData> roomTypeDictMap = null;
            Map<String, SysDictData> bedTypeDictMap = null;
            if (CollUtil.isNotEmpty(zhusuList)) {
                zhusuMap = zhusuList.stream().collect(Collectors.toMap(BsZhusu::getId, Function.identity()));
            }
            if (CollUtil.isNotEmpty(roomTypeDictList)) {
                roomTypeDictMap = roomTypeDictList.stream().collect(Collectors.toMap(SysDictData::getDictValue, Function.identity()));
            }
            if (CollUtil.isNotEmpty(bedTypeDictList)) {
                bedTypeDictMap = bedTypeDictList.stream().collect(Collectors.toMap(SysDictData::getDictValue, Function.identity()));
            }

            for (BsZhusuRoom room : roomList) {
                if (CollUtil.isNotEmpty(zhusuMap)) {
                    room.setZhusuName(ObjectUtil.isNotNull(zhusuMap.get(room.getZhusuId())) ? zhusuMap.get(room.getZhusuId()).getName() : "");
                }
                if (CollUtil.isNotEmpty(roomTypeDictMap)) {
                    room.setRoomTypeName(ObjectUtil.isNotNull(roomTypeDictMap.get(room.getRoomType())) ? roomTypeDictMap.get(room.getRoomType()).getDictLabel() : "");
                }
                if (CollUtil.isNotEmpty(bedTypeDictMap)) {
                    room.setBedTypeName(ObjectUtil.isNotNull(bedTypeDictMap.get(room.getBedType())) ? bedTypeDictMap.get(room.getBedType()).getDictLabel() : "");
                }
            }
        }
    }

}
